package javaSenior.threadExer;

/**
 * @author Lenl
 * @version v1.0
 * @create 2021-06-02 21:18
 * @description
 *
 * 1.问题：卖票过程中出现了重票和错票
 * 2.问题出现原因：当某个吸纳成操作车票过程中，某个线程也进来操作车票
 * 3.如何解决：当一个线程操作ticket时，其他车票不能参与进来，直到线程操作完时，其他线程才能进来，即使线程阻塞
 * 4.再java中通过同步机制来解决吸纳成安全问题
 *      方式一：同步代码块
 *          synchronized(同步监视器){
 *              //需要被同步的代码
 *          }
 *          说明：1.操作共享数据的代码，即为被同步的代码 -->不能包含多了，也不能包含少了
 *              2.共享数据：多个线程共同操作的变量，如ticket
 *              3.同步监视器，俗称，锁。任何一个类的对象都能充当锁
 *                  要求：多个线程必须要共用同一把锁
 *      方式二：同步方法
 *           如果操作共享数据的代码完整的声明在一个方法中，可以将该方法声明为同步的。
 *
 *
 *
 *
 * 5.使用同步方式，解决了线程安全问题。--好处
 *   操作同步代码块时，只能有一个线程参与，其他线程等待，相当于单线程
 *
 *
 */
public class WindowTest2 {
    public static void main(String[] args) {
        window1 w1=new window1();
        Thread t1=new Thread(w1);
        Thread t2=new Thread(w1);
        Thread t3=new Thread(w1);
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

class window1 implements Runnable{
    private int ticket=1000;
    Object obj =new Object();
    @Override
    public void run() {
        while (true){
        synchronized(this){
        if(ticket>0){
            //加了sleep容易出现-1
//            try {
//                Thread.sleep(100);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
            System.out.println(Thread.currentThread().getName()+"买票，票号为："+ticket--);
        }else {
            break;
        }
        }//同步代码块
        }
    }
}
